/*!
 * LMV v6.4.1
 * 
 * Copyright 2019 Autodesk, Inc.
 * All rights reserved.
 * 
 * This computer source code and related instructions and comments are the
 * unpublished confidential and proprietary information of Autodesk, Inc.
 * and are protected under Federal copyright and state trade secret law.
 * They may not be disclosed to, copied or used by any third party without
 * the prior written consent of Autodesk, Inc.
 * 
 * Autodesk Forge Viewer Usage Limitations:
 * 
 * The Autodesk Forge viewer can only be used to view files generated by
 * Autodesk Forge services. The Autodesk Forge Viewer JavaScript must be
 * delivered from an Autodesk hosted URL.
 */
Autodesk.Extensions.Wireframes =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./extensions/Wireframes/Wireframes.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./extensions/Wireframes/Wireframes.js":
/*!*********************************************!*\
  !*** ./extensions/Wireframes/Wireframes.js ***!
  \*********************************************/
/*! exports provided: default */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return WireframesExtension; });
function _typeof(obj) {if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {_typeof = function _typeof(obj) {return typeof obj;};} else {_typeof = function _typeof(obj) {return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;};}return _typeof(obj);}function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}function _createClass(Constructor, protoProps, staticProps) {if (protoProps) _defineProperties(Constructor.prototype, protoProps);if (staticProps) _defineProperties(Constructor, staticProps);return Constructor;}function _possibleConstructorReturn(self, call) {if (call && (_typeof(call) === "object" || typeof call === "function")) {return call;}return _assertThisInitialized(self);}function _assertThisInitialized(self) {if (self === void 0) {throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _getPrototypeOf(o) {_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {return o.__proto__ || Object.getPrototypeOf(o);};return _getPrototypeOf(o);}function _inherits(subClass, superClass) {if (typeof superClass !== "function" && superClass !== null) {throw new TypeError("Super expression must either be null or a function");}subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } });if (superClass) _setPrototypeOf(subClass, superClass);}function _setPrototypeOf(o, p) {_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {o.__proto__ = p;return o;};return _setPrototypeOf(o, p);}

var av = Autodesk.Viewing;

/**
                            * Provides the ability of rendering the model in wireframe mode.
                            * The method implemented is not very performant, so it's best to 
                            * avoid using it with large models.
                            * 
                            * The extension id is: `Autodesk.Viewing.Wireframes`
                            * 
                            * @example
                            *   viewer.loadExtension('Autodesk.Viewing.Wireframes')
                            * 
                            * @memberof Autodesk.Viewing.Extensions
                            * @alias Autodesk.Viewing.Extensions.WireframesExtension
                            * @see {@link Autodesk.Viewing.Extension} for common inherited methods.
                            * @constructor
                            */var
WireframesExtension = /*#__PURE__*/function (_av$Extension) {_inherits(WireframesExtension, _av$Extension);

  function WireframesExtension(viewer, options) {var _this;_classCallCheck(this, WireframesExtension);
    _this = _possibleConstructorReturn(this, _getPrototypeOf(WireframesExtension).call(this, viewer, options));

    _this.groups = [];
    _this.geometries = [];
    _this.materials = [];
    _this.lines = [];

    _this.lightPreset = 4; //"Photo Booth";
    _this.viewerLightPreset = 4;

    _this.showingSolidMaterials = true;
    _this.showingLines = true;

    _this.linesMaterial = new THREE.LineBasicMaterial({
      color: new THREE.Color(0x00000000),
      opacity: 0.03,
      transparent: true,
      depthTest: true,
      depthWrite: false });


    _this.solidMaterial = new THREE.MeshPhongMaterial({
      color: 0xFFCFCFCF,
      specular: 0x00000000,
      emissive: 0xFFCFCFCF,
      ambient: 0,
      opacity: 1.0,
      transparent: false,
      polygonOffset: true,
      polygonOffsetFactor: 1.0,
      polygonOffsetUnits: 5 });

    _this.solidMaterial.packedNormals = true;
    _this.name = 'wireframes';return _this;
  }_createClass(WireframesExtension, [{ key: "load", value: function load()

    {

      var togglePolygonOffset = function () {
        // Functionality available in Viewer 2.15 and up, to make wireframe lines
        // look better.
        // However, wirelines may still work (though not as good) when the function is not present.
        var matManager = this.viewer.impl.getMaterials();
        if (matManager && matManager.togglePolygonOffset) {
          matManager.togglePolygonOffset(true, 1.0, 5.0);
        }
      }.bind(this);

      // Create and add wireframe geometry.
      var createAndAddWireframes = function () {

        var viewer = this.viewer;
        var models = viewer.impl.modelQueue().getModels();
        var modelsCount = models.length;

        for (var i = 0; i < modelsCount; ++i) {

          if (!models[i].getData().instanceTree) {
            continue;
          }

          // Create group with all lines obtained for the model.
          var group = createWireframes(models[i], this.geometries, this.lines, this.materials, this.linesMaterial);
          group.model = models[i];
          this.groups.push(group);

          // Set solid material to new fragments only when tool is activated.
          if (this.activeStatus) {
            addWireframes(this.viewer, this.groups);
            this.setSolidMaterial(this.solidMaterial);
          }

        }

        togglePolygonOffset();
        viewer.impl.invalidate(true, true, true);
      }.bind(this);

      createAndAddWireframes();

      // Keep adding wireframes if model is still loading.
      this.viewer.addEventListener(Autodesk.Viewing.PROGRESS_UPDATE_EVENT,
      function (event) {
        if (event.state === Autodesk.Viewing.ProgressState.LOADING) {

          // Add wireframes for newly loaded fragments.
          createAndAddWireframes();
        }
      });

      // Enable line offset.
      togglePolygonOffset();

      return true;
    } }, { key: "unload", value: function unload()

    {

      this.activeStatus = false;

      revertSolidMaterials(this.viewer, this.materials);
      revertWireframes(this.viewer, this.groups);

      this.geometries = [];
      this.materials = [];
      this.lines = [];
      this.groups = [];

      return true;
    } }, { key: "activate",

    /**
                             * Enters wireframe mode.
                             * 
                             * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                             * @alias Autodesk.Viewing.Extensions.WireframesExtension#activate
                             */value: function activate()
    {

      this.activeStatus = true;

      this.viewerLightPreset = this.viewer.prefs.get('lightPreset');
      this.viewer.setLightPreset(this.lightPreset);

      this.setSolidMaterial(this.solidMaterial);
      this.setLinesMaterial(this.linesMaterial);

      addWireframes(this.viewer, this.groups);

      this.showSolidMaterial(this.showingSolidMaterials);
      this.showLines(this.showingLines);

      return true;
    } }, { key: "deactivate",

    /**
                               * Exits wireframe mode.
                               * 
                               * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                               * @alias Autodesk.Viewing.Extensions.WireframesExtension#deactivate
                               */value: function deactivate()
    {

      this.activeStatus = false;
      this.viewer.setLightPreset(this.viewerLightPreset);
      revertWireframes(this.viewer, this.groups);
      revertSolidMaterials(this.viewer, this.materials);
      return true;
    } }, { key: "showSolidMaterial",

    /**
                                      * Whether to replace the standard materials with a solid one, or not.
                                      * 
                                      * @param {bool} show
                                      * 
                                      * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                                      * @alias Autodesk.Viewing.Extensions.WireframesExtension#showSolidMaterial
                                      */value: function showSolidMaterial(
    show) {

      this.showingSolidMaterials = show;

      if (!this.activeStatus) {
        return;
      }

      if (this.showingSolidMaterials) {
        this.setSolidMaterial(this.solidMaterial);
      } else {
        revertSolidMaterials(this.viewer, this.materials);
      }
    } }, { key: "showLines",

    /**
                              * Whether to render line edges or not.
                              * 
                              * @param {bool} show
                              * 
                              * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                              * @alias Autodesk.Viewing.Extensions.WireframesExtension#showLines
                              */value: function showLines(
    show) {

      this.showingLines = show;

      if (!this.activeStatus) {
        return;
      }

      var lines = this.lines;
      var linesCount = lines.length;

      for (var i = 0; i < linesCount; ++i) {

        var line = lines[i];
        line.visible = show;
      }

      this.viewer.impl.invalidate(true, true, true);
    } }, { key: "setSolidMaterial",

    /**
                                     * Replaces the solid material.
                                     * 
                                     * @param {THREE.Material} material
                                     * 
                                     * @see {@link Autodesk.Viewing.Extensions.WireframesExtension#showSolidMaterial}
                                     * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                                     * @alias Autodesk.Viewing.Extensions.WireframesExtension#setSolidMaterial
                                     */value: function setSolidMaterial(
    material) {

      this.solidMaterial = material;

      // Replace all fragments materials if extension active and showing solid materials.
      if (!this.activeStatus || !this.showingSolidMaterials) {
        return;
      }

      var materials = this.materials;
      var materialsCount = materials.length;

      for (var i = 0; i < materialsCount; ++i) {

        var material = materials[i];
        material.fragments.setMaterial(material.fragment, this.solidMaterial);
      }

      this.viewer.impl.invalidate(true, true, true);
    } }, { key: "setLinesMaterial",

    /**
                                     * Replaces the line material.
                                     * 
                                     * @param {THREE.Material} material
                                     * 
                                     * @see {@link Autodesk.Viewing.Extensions.WireframesExtension#showLines}
                                     * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                                     * @alias Autodesk.Viewing.Extensions.WireframesExtension#setLinesMaterial
                                     */value: function setLinesMaterial(
    material) {

      this.linesMaterial = material;

      // Replace all lines materials if extension is active and showing lines.
      if (!this.activeStatus || !this.showingLines) {
        return;
      }

      var lines = this.lines;
      var linesCount = lines.length;

      for (var i = 0; i < linesCount; ++i) {

        var line = lines[i];
        line.material = this.linesMaterial;
      }

      this.viewer.impl.invalidate(true, true, true);
    } }, { key: "setLightPreset",

    /**
                                   * Specifies the light preset to use when wireframe mode is activated.
                                   * 
                                   * @param {string} name - the name of the light preset
                                   * 
                                   * @memberof Autodesk.Viewing.Extensions.WireframesExtension
                                   * @alias Autodesk.Viewing.Extensions.WireframesExtension#setLightPreset
                                   */value: function setLightPreset(
    name) {

      this.lightPreset = name;
      if (this.activeStatus) {
        this.viewer.setLightPreset(name);
      }
    } }]);return WireframesExtension;}(av.Extension);




function createWireframes(model, geometries, lines, materials, linesMaterial) {

  // Get Meshes in the model.
  var tree = model.getData().instanceTree;
  var fragments = model.getFragmentList();
  var newGeometries = [];

  tree.enumNodeChildren(model.getRootId(), function (dbId) {

    if (tree.isNodeHidden(dbId) || tree.isNodeOff(dbId)) {
      return;
    }

    //All fragments that belong to the same node make part of the
    //same object so we have to accumulate all their intersections into one list
    tree.enumNodeFragments(dbId, function (fragmentId) {

      var mesh = fragments.getVizmesh(fragmentId);

      if (!mesh.geometry) {
        return;
      }

      if (mesh.geometry.is2d || mesh.geometry.isLines) {
        return;
      }

      if (!mesh.material.cutplanes) {
        return;
      }

      // Save materials to restore later.
      materials.push({ fragment: fragmentId, fragments: fragments, material: fragments.getMaterial(fragmentId) });

      // Add geometry if not already present.
      var geometry = fragments.getGeometry(fragmentId);
      if (!find(geometry, fragmentId, geometries)) {

        var world = new THREE.Matrix4();
        fragments.getWorldMatrix(fragmentId, world);
        newGeometries.push({ geometry: geometry, world: world, fragment: fragmentId });
      }
    }.bind(this), false);
  }, true);

  // Create wire lines.
  var group = new THREE.Group();
  var newGeometriesCount = newGeometries.length;
  var position = new THREE.Vector3(),quaternion = new THREE.Quaternion(),scale = new THREE.Vector3();

  for (var i = 0; i < newGeometriesCount; ++i) {

    var geometry = new THREE.Geometry();
    var geometryVertices = geometry.vertices;

    var srcWorld = newGeometries[i].world;
    var srcGeometry = newGeometries[i].geometry;

    var srcVertices = srcGeometry.vb;
    var srcIndices = srcGeometry.ib;
    var srcStride = srcGeometry.vbstride;

    for (var j = 0; j < srcIndices.length;) {

      var indexA = srcIndices[j++] * srcStride;
      var indexB = srcIndices[j++] * srcStride;
      var indexC = srcIndices[j++] * srcStride;

      var vertexA = new THREE.Vector3(srcVertices[indexA++], srcVertices[indexA++], srcVertices[indexA]);
      var vertexB = new THREE.Vector3(srcVertices[indexB++], srcVertices[indexB++], srcVertices[indexB]);
      var vertexC = new THREE.Vector3(srcVertices[indexC++], srcVertices[indexC++], srcVertices[indexC]);

      geometryVertices.push(vertexA);
      geometryVertices.push(vertexB);

      geometryVertices.push(vertexB);
      geometryVertices.push(vertexC);

      geometryVertices.push(vertexC);
      geometryVertices.push(vertexA);
    }

    var line = new THREE.Line(geometry, linesMaterial, THREE.LinePieces);

    srcWorld.decompose(position, quaternion, scale);
    line.position.copy(position);
    line.quaternion.copy(quaternion);
    line.scale.copy(scale);
    lines.push(line);

    group.add(line);
    geometries.push(newGeometries[i]);
  }

  return group;
}

function addWireframes(viewer, groups) {

  var groupsCount = groups.length;
  for (var i = 0; i < groupsCount; ++i) {

    viewer.impl.sceneAfter.add(groups[i]);
  }
  viewer.impl.invalidate(true, true, true);
}

function revertSolidMaterials(viewer, materials) {

  var materialsLength = materials.length;
  for (var i = 0; i < materialsLength; ++i) {

    var material = materials[i];
    material.fragments.setMaterial(material.fragment, material.material);
  }
  viewer.impl.invalidate(true, true, true);
}

function revertWireframes(viewer, groups) {

  var groupsCount = groups.length;
  for (var i = 0; i < groupsCount; ++i) {

    viewer.impl.sceneAfter.remove(groups[i]);
  }
  viewer.impl.invalidate(true, true, true);
}

function find(geometry, fragment, geometries) {

  var geometryCount = geometries.length;
  for (var i = 0; i < geometryCount; ++i) {

    if (geometries[i].geometry === geometry && geometries[i].fragment === fragment) {
      return geometries[i];
    }
  }

  return null;
}


Autodesk.Viewing.theExtensionManager.registerExtension('Autodesk.Viewing.Wireframes', WireframesExtension);

/***/ })

/******/ });